package com.company.finance.ddd.domain.core.voucher.rule;

/**
 * 不同大类的单据会生成一种或多种不同类型的凭证记录 -- 如采购单会生成3种凭证
 *
 * 凭证生成规则类命名规范 : 是否预付(P) + 是否关联交易(R) + 凭证类型
 * 通过统计 凭证生成规则共计55项, 因此concrete包中的类为55个, 可以根据凭证类型将规则class放入不同包中,
 * 也可通过责任链模式根据凭证类型, 单据类型设计规则class,可一定程度上解决类膨胀的问题.
 *
 * 重构 2021-8-21
 * 由于凭证类型数量更少，因此决定以凭证类型为基础，在其基础上添加可以识别出一个表单的BillSpecification，
 * 如此可避免根据 单据子类 + 是否预付 + 是否关联交易 + 凭证类型 来组合出所有凭证生成规则类，
 * 从而解决类膨胀的问题。
 * @author wanglei
 * @version $$Id: Rule, v 0.1 2021/2/3 14:22 wanglei Exp $$
 */
public abstract class RuleHolder {

    private final RuleDefinition ruleDefinition;

    protected RuleHolder() {
        this.ruleDefinition = createRuleDefinition();
    }

    public RuleDefinition getRuleDefinition() {
        return ruleDefinition;
    }

    /**
     * 本方法用于定义一个凭证类型{@link VoucherType}将对应几个单据标识, 也就是哪几种标识的单据将会生成哪一个类型的凭证。
     * {@see com.company.finance.ddd.domain.core.voucher.rule.RuleDefinition.BillSpecification}
     * @return RuleDefinition
     */
    protected abstract RuleDefinition createRuleDefinition();

    @Override
    public String toString() {
        return "AbsRule{" +
                "ruleIdentifying=" + ruleDefinition +
                '}';
    }
}
